
<!DOCTYPE html>
<!--[if IEMobile 7 ]><html class="no-js iem7"><![endif]-->
<!--[if lt IE 9]><html class="no-js lte-ie8"><![endif]-->
<!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]-->
<head>
  <meta charset="utf-8">
  <title>ksnowlv</title>
  <meta name="author" content="律威">

  
  <meta name="description" content="时序图（Sequence Diagram） 显示对象之间交互的图，这些对象是按时间顺序排列的。 时序图中包括的建模元素主要有： 1.对象（Actor）
2.生命线（Lifeline）
3.控制焦点（Focus of control）
4.消息（Message）:消息有同步消息，异步消息，返回消息 &hellip;">
  

  <!-- http://t.co/dKP3o1e -->
  <meta name="HandheldFriendly" content="True">
  <meta name="MobileOptimized" content="320">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  
  <link rel="canonical" href="http://ksnowlv.github.io/blog/page/4">
  <link href="/favicon.png" rel="icon">
  <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
  <link href="/atom.xml" rel="alternate" title="ksnowlv" type="application/atom+xml">
  <script src="/javascripts/modernizr-2.0.js"></script>
  <script src="//ajax.useso.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script>!window.jQuery && document.write(unescape('%3Cscript src="./javascripts/lib/jquery.min.js"%3E%3C/script%3E'))</script>
  <script src="/javascripts/octopress.js" type="text/javascript"></script>
  <!--Fonts from Google"s Web font directory at http://google.com/webfonts -->
<link href="http://fonts.useso.com/css?family=PT+Serif:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
<link href="http://fonts.useso.com/css?family=PT+Sans:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">

  
  <script type="text/javascript">
    var _gaq = _gaq || [];
     _gaq.push(['_setAccount', 'UA-39546615-2']);
    // _gaq.push(['_trackPageview']);

    // (function() {
    //   var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    //   ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    //   var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
    // })();

    _gaq.push(['_trackPageview']);

      (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src='http://droidyue-tools.qiniudn.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
      })();
  </script>


</head>

<body   >
  <header role="banner"><hgroup>
  <h1><a href="/">ksnowlv</a></h1>
  
    <h2>回顾过去,总结以往;立足现在,铭记当下;技术为主,笔记而已.</h2>
  
</hgroup>

</header>
  <nav role="navigation"><ul class="subscription" data-subscription="rss">
  <li><a href="/atom.xml" rel="subscribe-rss" title="subscribe via RSS">RSS</a></li>
  
</ul>
  
<form action="http://google.com/search" method="get">
  <fieldset role="search">
    <input type="hidden" name="q" value="site:ksnowlv.github.io" />
    <input class="search" type="text" name="q" results="0" placeholder="Search"/>
  </fieldset>
</form>
  
<ul class="main-navigation">
  <li><a href="/">博客首页</a></li>
  <li><a href="/blog/archives">文章列表</a></li>
  <!-- <li><a href="/about-me">关于我</a></li>
 -->
</ul>

</nav>
  <div id="main">
    <div id="content">
      <div class="blog-index">
  
  
  
    <article>
      
  <header>
    
      <h1 class="entry-title"><a href="/blog/2014/11/03/uml-shi-xu-tu/">Uml时序图</a></h1>
    
    
      <p class="meta">
        








  


<time datetime="2014-11-03T16:14:00+08:00" pubdate data-updated="true">Nov 3<span>rd</span>, 2014</time>
        
         | <a href="/blog/2014/11/03/uml-shi-xu-tu/#disqus_thread">Comments</a>
        
      </p>
    
  </header>


  <div class="entry-content"><h3>时序图（Sequence Diagram）</h3>

<pre><code>显示对象之间交互的图，这些对象是按时间顺序排列的。
</code></pre>

<h3>时序图中包括的建模元素主要有：</h3>

<ul>
<li>1.对象（Actor）</li>
<li>2.生命线（Lifeline）</li>
<li>3.控制焦点（Focus of control）</li>
<li>4.消息（Message）:消息有同步消息，异步消息，返回消息。</li>
</ul>


<h3>时序图参考如下：</h3>

<p><img src="/images/post/2014-11-03-uml-shi-xu-tu/sequence_diagram.jpg" alt="image" /></p>
</div>
  
  


    </article>
  
  
    <article>
      
  <header>
    
      <h1 class="entry-title"><a href="/blog/2014/11/03/uml-lei-tu/">Uml类图</a></h1>
    
    
      <p class="meta">
        








  


<time datetime="2014-11-03T11:28:00+08:00" pubdate data-updated="true">Nov 3<span>rd</span>, 2014</time>
        
         | <a href="/blog/2014/11/03/uml-lei-tu/#disqus_thread">Comments</a>
        
      </p>
    
  </header>


  <div class="entry-content"><h3>类之间的关系有关联、聚合、组合、泛化、依赖。</h3>

<ul>
<li>1.关联：是类之间的一种很弱的联系。关联可以有方向，可以是单向关联，也可以是双向关联。</li>
<li>2.聚合：是一种特殊的关联，聚合表示整体与部分的关系。整体类是由组成类聚合而成。例如鱼群与鱼，人群与人。</li>
<li>3.组合：也是一种特殊的关联，也表示类之间整体和部分的关系，但是组合关系中部分和整体具有统一的生存期。一旦整体对象不存在，部分对象也将不存在。</li>
<li>4.泛化：定义父类与子类之间的关系，也就是继承关系。泛化关系是“a－kind－of”关系。</li>
<li>5.依赖：一个类依赖于另一个类的功能。如果A类与B类有关联关系，它们必然有依赖关系。如果两个类有关联关系时，不用再表示出这两个类之间的依赖系统。</li>
<li>6.实现：类对接口类的继承与实现（可以是多个）。</li>
</ul>


<h3>类图参考如下：</h3>

<p><img src="/images/post/2014-11-03-uml-lei-tu/class_diagram.jpg" alt="image" /></p>
</div>
  
  


    </article>
  
  
    <article>
      
  <header>
    
      <h1 class="entry-title"><a href="/blog/2014/10/27/uml-yong-li-tu/">Uml-用例图</a></h1>
    
    
      <p class="meta">
        








  


<time datetime="2014-10-27T17:15:00+08:00" pubdate data-updated="true">Oct 27<span>th</span>, 2014</time>
        
         | <a href="/blog/2014/10/27/uml-yong-li-tu/#disqus_thread">Comments</a>
        
      </p>
    
  </header>


  <div class="entry-content"><h3>用例图(Use Case)</h3>

<pre><code>主要用来描述“用户、需求、系统功能单元”之间的关系.
</code></pre>

<p>用例图所包含的元素</p>

<h4>1.参与者(Actor)</h4>

<h4>2.用例(Use Case)</h4>

<pre><code>外部可见的系统功能,用椭圆表示
</code></pre>

<h4>3.子系统(Subsystem)</h4>

<pre><code>用来展示系统的一部分功能，这部分功能联系紧密。
</code></pre>

<h4>4.关系</h4>

<pre><code>用例图中涉及的关系有：关联、泛化、包含、扩展。
</code></pre>

<ul>
<li>a.关联(Association):表示参与者与用例之间的通信，任何一方都可发送或接受消息.</li>
<li>b.泛化(Inheritance):继承关系，子用例和父用例相似，但表现出更特别的行为.</li>
<li>c.包含(Include):包含关系用来把一个较复杂用例所表示的功能分解成较小的功能.</li>
<li>d.扩展(Extend):指用例功能的延伸，相当于为基础用例提供一个附加功能.
　 <br/>
示例图：</li>
</ul>


<p><img src="/images/post/2014-10-27-uml-yong-li-tu/case_diagram.jpg" alt="image" />
　　
用例图也许并不能很好地表达系统的需求，有时需要添加用例描述表来说明.</p>
</div>
  
  


    </article>
  
  
    <article>
      
  <header>
    
      <h1 class="entry-title"><a href="/blog/2014/10/24/cocoaspdy-li-jie/">CocoaSPDY理解</a></h1>
    
    
      <p class="meta">
        








  


<time datetime="2014-10-24T16:54:00+08:00" pubdate data-updated="true">Oct 24<span>th</span>, 2014</time>
        
         | <a href="/blog/2014/10/24/cocoaspdy-li-jie/#disqus_thread">Comments</a>
        
      </p>
    
  </header>


  <div class="entry-content"><h3>源码见<a href="https://github.com/twitter/CocoaSPDY">https://github.com/twitter/CocoaSPDY</a></h3>

<p>其类图如下：</p>

<p><img src="/images/post/2014-10-24-cocoaspdy-li-jie/CocoaSPDY_class_overview.jpg" alt="image" /></p>
</div>
  
  


    </article>
  
  
    <article>
      
  <header>
    
      <h1 class="entry-title"><a href="/blog/2014/10/23/ios-spdy/">iOS Spdy概览</a></h1>
    
    
      <p class="meta">
        








  


<time datetime="2014-10-23T17:00:00+08:00" pubdate data-updated="true">Oct 23<span>rd</span>, 2014</time>
        
         | <a href="/blog/2014/10/23/ios-spdy/#disqus_thread">Comments</a>
        
      </p>
    
  </header>


  <div class="entry-content"><p> <a href="http://baike.baidu.com/view/2984528.htm?fr=aladdin">SPDY</a>是Google开发的基于TCP的应用层协议,谷歌表示，引入SPDY协议后，在实验室测试中页面加载速度比原先快64%。</p>

<h3>1.SPDY相关资料</h3>

<ul>
<li>1.<a href="http://www.fireflysource.com/spdy/spdy-v3-cn.html">SPDY协议 &ndash; v3</a></li>
<li>2.<a href="http://blog.csdn.net/hursing/article/details/22785475">SPDY、HTTP/2、QUIC协议</a></li>
<li>3.<a href="http://www.chromium.org/spdy/spdy-whitepaper">SPDY: An experimental protocol for a faster web</a></li>
<li>4.<a href="http://wufawei.com/2013/12/introduction-to-spdy/">SPDY简介</a></li>
<li>5.<a href="http://spdycheck.org">spdycheck</a></li>
</ul>


<h3>2.SPDY开源项目</h3>

<ul>
<li>1.<a href="https://github.com/tatsuhiro-t/spdylay">spdylay</a>：C版本的开源库</li>
<li>2.<a href="https://github.com/twitter/CocoaSPDY">CocoaSPDY</a>：Twitter推出用于iOS和Mac OS X的SPDY框架，适用于iOS和Mac OS X的SPDY/3.1</li>
<li>3.<a href="https://github.com/locationlabs/SPDY-for-iPhone.git">SPDY-for-iPhone</a></li>
<li>4.<a href="https://github.com/Voxer/iSPDY">iSPDY</a>，可参见博客<a href="http://engineering.voxer.com/2014/01/03/ispdy-released/">http://engineering.voxer.com/2014/01/03/ispdy-released/</a></li>
<li>5.<a href="http://www.chromium.org/spdy/">The Chromium Projects</a></li>
</ul>


<h3>3.其它</h3>

<ul>
<li><ol>
<li>iOS 8 和优胜美地开始支持SPDY协议，可参考wwdc 2014中的<a href="http://devstreaming.apple.com/videos/wwdc/2014/707xx1o5tdjnvg9/707/707_whats_new_in_foundation_networking.pdf?dl=1">What&rsquo;s New in Foundation Networking</a></li>
</ol>
</li>
<li><ol>
<li>目前iOS spdy的实现方案是针对<strong>NSURLConnection</strong>或<strong>NSURLSession</strong>通过<strong>NSURLProtocol</strong>进行拦截。那对于非使用这两种方式实现的网络模块无效果。同时，一个app当中可能会出现多个<strong>NSURLProtocol</strong>拦截的场景，要避免拦截失效的情况。</li>
</ol>
</li>
<li>3.下面会介绍下Twitter推出用于iOS和Mac OS X的SPDY框架- <a href="https://github.com/twitter/CocoaSPDY">CocoaSPDY</a>:大体采用的实现方案是类似的，处理细节上可能会有差异。</li>
</ul>

</div>
  
  


    </article>
  
  
    <article>
      
  <header>
    
      <h1 class="entry-title"><a href="/blog/2014/10/22/ios-zhi-keychain/">iOS之Keychain</a></h1>
    
    
      <p class="meta">
        








  


<time datetime="2014-10-22T17:51:00+08:00" pubdate data-updated="true">Oct 22<span>nd</span>, 2014</time>
        
         | <a href="/blog/2014/10/22/ios-zhi-keychain/#disqus_thread">Comments</a>
        
      </p>
    
  </header>


  <div class="entry-content"><p>iOS之Keychain用途:提供了一种安全的保存私密信息的方式，每个ios程序都有一个独立的keychain存储,它保存的信息不会因App被删除而丢失，也可用于跨App共享keychain信息。见苹果开发文档<a href="https://developer.apple.com/library/ios/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html#//apple_ref/doc/uid/TP30000897-CH204-TP9">Keychain Services Programming Guide</a></p>

<p>Keychain Services Reference关键的方法如下</p>

<ul>
<li>SecItemCopyMatching</li>
<li>SecItemAdd</li>
<li>SecItemUpdate</li>
<li>SecItemDelete</li>
</ul>


<p>苹果官方提供了的demo程序<a href="https://developer.apple.com/library/ios/samplecode/GenericKeychain/Introduction/Intro.html">GenericKeychain</a>，使用苹果封装的<code>KeychainItemWrapper.h</code>和<code>KeychainItemWrapper.m</code>提供的接口即可。</p>

<p>代码示例如下：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'>    <span class="n">KeychainItemWrapper</span> <span class="o">*</span><span class="n">uuid</span> <span class="o">=</span> <span class="p">[[</span><span class="n">KeychainItemWrapper</span> <span class="n">alloc</span><span class="p">]</span>
</span><span class='line'>                                         <span class="nl">initWithIdentifier:</span><span class="s">@&quot;UUID&quot;</span>
</span><span class='line'>                                         <span class="nl">accessGroup:</span><span class="s">@&quot;com.taobao.userinfo&quot;</span><span class="p">];</span>
</span><span class='line'>    <span class="n">NSString</span> <span class="o">*</span><span class="n">strUUID</span> <span class="o">=</span> <span class="p">[</span><span class="n">uuid</span> <span class="nl">objectForKey:</span><span class="p">(</span><span class="n">__bridge</span> <span class="kt">id</span><span class="p">)</span><span class="n">kSecValueData</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">strUUID</span><span class="p">.</span><span class="n">length</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">CFUUIDRef</span> <span class="n">uuidRef</span> <span class="o">=</span> <span class="n">CFUUIDCreate</span><span class="p">(</span><span class="n">kCFAllocatorDefault</span><span class="p">);</span>
</span><span class='line'>        <span class="n">strUUID</span> <span class="o">=</span>  <span class="n">CFBridgingRelease</span><span class="p">(</span><span class="n">CFUUIDCreateString</span> <span class="p">(</span><span class="n">kCFAllocatorDefault</span><span class="p">,</span><span class="n">uuidRef</span><span class="p">));</span>
</span><span class='line'>
</span><span class='line'>        <span class="p">[</span><span class="n">uuid</span> <span class="nl">setObject:</span><span class="n">strUUID</span> <span class="nl">forKey:</span><span class="p">(</span><span class="n">__bridge</span> <span class="kt">id</span><span class="p">)</span><span class="n">kSecValueData</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;create uuid&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="n">CFRelease</span><span class="p">(</span><span class="n">uuidRef</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;uuid = %@&quot;</span><span class="p">,</span><span class="n">strUUID</span><span class="p">);</span>
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>


<p>可参考<a href="https://github.com/ksnowlv/KeyChainTest.git">源代码</a>，该工程中的<code>KeychainItemWrapper.h</code>和<code>KeychainItemWrapper.m</code>是支持<strong>ARC</strong>的。</p>
</div>
  
  


    </article>
  
  
    <article>
      
  <header>
    
      <h1 class="entry-title"><a href="/blog/2014/10/21/ios-push-ji-zhi/">iOS Push机制</a></h1>
    
    
      <p class="meta">
        








  


<time datetime="2014-10-21T15:57:00+08:00" pubdate data-updated="true">Oct 21<span>st</span>, 2014</time>
        
         | <a href="/blog/2014/10/21/ios-push-ji-zhi/#disqus_thread">Comments</a>
        
      </p>
    
  </header>


  <div class="entry-content"><h3>一. push原理</h3>

<p>iOS push工作机制可以使用下图概括：
<img src="/images/post/2014-10-21-ios-push-ji-zhi/apple_push_overview.png" alt="image" /></p>

<ul>
<li>Provider:应用自己的服务器；</li>
<li>APNS:Apple Push Notification Service的简称，苹果Push服务器.</li>
</ul>


<p>可以简化为：
<img src="/images/post/2014-10-21-ios-push-ji-zhi/apple_push_flow_diagram.jpg" alt="image" /></p>

<h3>二. push执行时序</h3>

<p>可由下图示意：</p>

<p><img src="/images/post/2014-10-21-ios-push-ji-zhi/apple_push_timing_diagram.jpg" alt="image" /></p>

<h3>三. push for iOS客户端-deviceToken</h3>

<p><img src="/images/post/2014-10-21-ios-push-ji-zhi/apple_push_flow_diagram_for_client.jpg" alt="image" /></p>

<h4>.关于客户端获取deviceToken</h4>

<p>   服务端要发送push消息给某一设备还必须知道该设备的deviceToken。应用运行后获取到deviceToken，然后上传给服务器.
   下面介绍如何获取deviceToken?</p>

<ul>
<li><ol>
<li>应用必须先注册使用push功能。</li>
</ol>
</li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">BOOL</span><span class="p">)</span><span class="nf">application:</span><span class="p">(</span><span class="n">UIApplication</span> <span class="o">*</span><span class="p">)</span><span class="nv">application</span> <span class="nf">didFinishLaunchingWithOptions:</span><span class="p">(</span><span class="n">NSDictionary</span> <span class="o">*</span><span class="p">)</span><span class="nv">launchOptions</span> <span class="p">{</span>
</span><span class='line'>      <span class="p">[[</span><span class="n">UIApplication</span> <span class="n">sharedApplication</span><span class="p">]</span> <span class="nl">registerForRemoteNotificationTypes:</span><span class="p">(</span><span class="n">UIRemoteNotificationTypeAlert</span> <span class="o">|</span> <span class="n">UIRemoteNotificationTypeSound</span> <span class="o">|</span> <span class="n">UIRemoteNotificationTypeBadge</span><span class="p">)];</span>
</span><span class='line'>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<ul>
<li>2.在AppDelegate中添加下面方法来获取deviceToken：</li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="c1">// Delegation methods</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">application:</span><span class="p">(</span><span class="n">UIApplication</span> <span class="o">*</span><span class="p">)</span><span class="nv">app</span> <span class="nf">didRegisterForRemoteNotificationsWithDeviceToken:</span><span class="p">(</span><span class="n">NSData</span> <span class="o">*</span><span class="p">)</span><span class="nv">devToken</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">devTokenBytes</span> <span class="o">=</span> <span class="p">[</span><span class="n">devToken</span> <span class="n">bytes</span><span class="p">];</span>
</span><span class='line'>    <span class="n">self</span><span class="p">.</span><span class="n">registered</span> <span class="o">=</span> <span class="n">YES</span><span class="p">;</span>
</span><span class='line'>    <span class="p">[</span><span class="n">self</span> <span class="nl">sendProviderDeviceToken:</span><span class="n">devTokenBytes</span><span class="p">];</span> <span class="c1">// custom method</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">application:</span><span class="p">(</span><span class="n">UIApplication</span> <span class="o">*</span><span class="p">)</span><span class="nv">app</span> <span class="nf">didFailToRegisterForRemoteNotificationsWithError:</span><span class="p">(</span><span class="n">NSError</span> <span class="o">*</span><span class="p">)</span><span class="nv">err</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Error in registration. Error: %@&quot;</span><span class="p">,</span> <span class="n">err</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>应用获取到deviceToken后，上传给Provider，Provider就可以用这个deviceToken给这个设备push消息了。</p>

<pre><code>通常情况下，deviceToken是不会改变的；有时同一台设备可能有不同的deviceToken。关于该主题可以搜索相关内容
所以，当deviceToken改变时一定要通知服务器更新。
</code></pre>

<h3>四.push for provider</h3>

<p>服务器配置好证书并拿到deviceToken后就可以向APNS发送消息了. 发送消息的格式有两种：</p>

<ul>
<li>1.简单消息格式</li>
</ul>


<p><img src="/images/post/2014-10-21-ios-push-ji-zhi/apple_push_payload_simple.png" alt="image" /></p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="k">static</span> <span class="n">bool</span> <span class="nf">sendPayload</span><span class="p">(</span><span class="n">SSL</span> <span class="o">*</span><span class="n">sslPtr</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">deviceTokenBinary</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">payloadBuff</span><span class="p">,</span> <span class="n">size_t</span> <span class="n">payloadLength</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">bool</span> <span class="n">rtn</span> <span class="o">=</span> <span class="n">false</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">sslPtr</span> <span class="o">&amp;&amp;</span> <span class="n">deviceTokenBinary</span> <span class="o">&amp;&amp;</span> <span class="n">payloadBuff</span> <span class="o">&amp;&amp;</span> <span class="n">payloadLength</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">uint8_t</span> <span class="n">command</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="cm">/* command number */</span>
</span><span class='line'>        <span class="kt">char</span> <span class="n">binaryMessageBuff</span><span class="p">[</span><span class="k">sizeof</span><span class="p">(</span><span class="n">uint8_t</span><span class="p">)</span> <span class="o">+</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint16_t</span><span class="p">)</span> <span class="o">+</span>
</span><span class='line'>            <span class="n">DEVICE_BINARY_SIZE</span> <span class="o">+</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint16_t</span><span class="p">)</span> <span class="o">+</span> <span class="n">MAXPAYLOAD_SIZE</span><span class="p">];</span>
</span><span class='line'>        <span class="cm">/* message format is, |COMMAND|TOKENLEN|TOKEN|PAYLOADLEN|PAYLOAD| */</span>
</span><span class='line'>        <span class="kt">char</span> <span class="o">*</span><span class="n">binaryMessagePt</span> <span class="o">=</span> <span class="n">binaryMessageBuff</span><span class="p">;</span>
</span><span class='line'>        <span class="n">uint16_t</span> <span class="n">networkOrderTokenLength</span> <span class="o">=</span> <span class="n">htons</span><span class="p">(</span><span class="n">DEVICE_BINARY_SIZE</span><span class="p">);</span>
</span><span class='line'>        <span class="n">uint16_t</span> <span class="n">networkOrderPayloadLength</span> <span class="o">=</span> <span class="n">htons</span><span class="p">(</span><span class="n">payloadLength</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="cm">/* command */</span>
</span><span class='line'>        <span class="o">*</span><span class="n">binaryMessagePt</span><span class="o">++</span> <span class="o">=</span> <span class="n">command</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>       <span class="cm">/* token length network order */</span>
</span><span class='line'>        <span class="n">memcpy</span><span class="p">(</span><span class="n">binaryMessagePt</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">networkOrderTokenLength</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint16_t</span><span class="p">));</span>
</span><span class='line'>        <span class="n">binaryMessagePt</span> <span class="o">+=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint16_t</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="cm">/* device token */</span>
</span><span class='line'>        <span class="n">memcpy</span><span class="p">(</span><span class="n">binaryMessagePt</span><span class="p">,</span> <span class="n">deviceTokenBinary</span><span class="p">,</span> <span class="n">DEVICE_BINARY_SIZE</span><span class="p">);</span>
</span><span class='line'>        <span class="n">binaryMessagePt</span> <span class="o">+=</span> <span class="n">DEVICE_BINARY_SIZE</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="cm">/* payload length network order */</span>
</span><span class='line'>        <span class="n">memcpy</span><span class="p">(</span><span class="n">binaryMessagePt</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">networkOrderPayloadLength</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint16_t</span><span class="p">));</span>
</span><span class='line'>        <span class="n">binaryMessagePt</span> <span class="o">+=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint16_t</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="cm">/* payload */</span>
</span><span class='line'>        <span class="n">memcpy</span><span class="p">(</span><span class="n">binaryMessagePt</span><span class="p">,</span> <span class="n">payloadBuff</span><span class="p">,</span> <span class="n">payloadLength</span><span class="p">);</span>
</span><span class='line'>        <span class="n">binaryMessagePt</span> <span class="o">+=</span> <span class="n">payloadLength</span><span class="p">;</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">SSL_write</span><span class="p">(</span><span class="n">sslPtr</span><span class="p">,</span> <span class="n">binaryMessageBuff</span><span class="p">,</span> <span class="p">(</span><span class="n">binaryMessagePt</span> <span class="o">-</span> <span class="n">binaryMessageBuff</span><span class="p">))</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
</span><span class='line'>            <span class="n">rtn</span> <span class="o">=</span> <span class="n">true</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">rtn</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li>2.增强型消息格式
<img src="/images/post/2014-10-21-ios-push-ji-zhi/apple_push_payload_Enhanced.png" alt="image" /></li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="k">static</span> <span class="n">bool</span> <span class="nf">sendPayload</span><span class="p">(</span><span class="n">SSL</span> <span class="o">*</span><span class="n">sslPtr</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">deviceTokenBinary</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">payloadBuff</span><span class="p">,</span> <span class="n">size_t</span> <span class="n">payloadLength</span><span class="p">)</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>  <span class="n">bool</span> <span class="n">rtn</span> <span class="o">=</span> <span class="n">false</span><span class="p">;</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="n">sslPtr</span> <span class="o">&amp;&amp;</span> <span class="n">deviceTokenBinary</span> <span class="o">&amp;&amp;</span> <span class="n">payloadBuff</span> <span class="o">&amp;&amp;</span> <span class="n">payloadLength</span><span class="p">)</span>
</span><span class='line'>  <span class="p">{</span>
</span><span class='line'>      <span class="n">uint8_t</span> <span class="n">command</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="cm">/* command number */</span>
</span><span class='line'>      <span class="kt">char</span> <span class="n">binaryMessageBuff</span><span class="p">[</span><span class="k">sizeof</span><span class="p">(</span><span class="n">uint8_t</span><span class="p">)</span> <span class="o">+</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint32_t</span><span class="p">)</span> <span class="o">+</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint32_t</span><span class="p">)</span> <span class="o">+</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint16_t</span><span class="p">)</span> <span class="o">+</span>
</span><span class='line'>          <span class="n">DEVICE_BINARY_SIZE</span> <span class="o">+</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint16_t</span><span class="p">)</span> <span class="o">+</span> <span class="n">MAXPAYLOAD_SIZE</span><span class="p">];</span>
</span><span class='line'>      <span class="cm">/* message format is, |COMMAND|ID|EXPIRY|TOKENLEN|TOKEN|PAYLOADLEN|PAYLOAD| */</span>
</span><span class='line'>      <span class="kt">char</span> <span class="o">*</span><span class="n">binaryMessagePt</span> <span class="o">=</span> <span class="n">binaryMessageBuff</span><span class="p">;</span>
</span><span class='line'>      <span class="n">uint32_t</span> <span class="n">whicheverOrderIWantToGetBackInAErrorResponse_ID</span> <span class="o">=</span> <span class="mi">1234</span><span class="p">;</span>
</span><span class='line'>      <span class="n">uint32_t</span> <span class="n">networkOrderExpiryEpochUTC</span> <span class="o">=</span> <span class="n">htonl</span><span class="p">(</span><span class="n">time</span><span class="p">(</span><span class="nb">NULL</span><span class="p">)</span><span class="o">+</span><span class="mi">86400</span><span class="p">);</span> <span class="c1">// expire message if not delivered in 1 day</span>
</span><span class='line'>      <span class="n">uint16_t</span> <span class="n">networkOrderTokenLength</span> <span class="o">=</span> <span class="n">htons</span><span class="p">(</span><span class="n">DEVICE_BINARY_SIZE</span><span class="p">);</span>
</span><span class='line'>      <span class="n">uint16_t</span> <span class="n">networkOrderPayloadLength</span> <span class="o">=</span> <span class="n">htons</span><span class="p">(</span><span class="n">payloadLength</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>      <span class="cm">/* command */</span>
</span><span class='line'>      <span class="o">*</span><span class="n">binaryMessagePt</span><span class="o">++</span> <span class="o">=</span> <span class="n">command</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>     <span class="cm">/* provider preference ordered ID */</span>
</span><span class='line'>     <span class="n">memcpy</span><span class="p">(</span><span class="n">binaryMessagePt</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">whicheverOrderIWantToGetBackInAErrorResponse_ID</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint32_t</span><span class="p">));</span>
</span><span class='line'>     <span class="n">binaryMessagePt</span> <span class="o">+=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint32_t</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>     <span class="cm">/* expiry date network order */</span>
</span><span class='line'>     <span class="n">memcpy</span><span class="p">(</span><span class="n">binaryMessagePt</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">networkOrderExpiryEpochUTC</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint32_t</span><span class="p">));</span>
</span><span class='line'>     <span class="n">binaryMessagePt</span> <span class="o">+=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint32_t</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>     <span class="cm">/* token length network order */</span>
</span><span class='line'>      <span class="n">memcpy</span><span class="p">(</span><span class="n">binaryMessagePt</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">networkOrderTokenLength</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint16_t</span><span class="p">));</span>
</span><span class='line'>      <span class="n">binaryMessagePt</span> <span class="o">+=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint16_t</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>      <span class="cm">/* device token */</span>
</span><span class='line'>      <span class="n">memcpy</span><span class="p">(</span><span class="n">binaryMessagePt</span><span class="p">,</span> <span class="n">deviceTokenBinary</span><span class="p">,</span> <span class="n">DEVICE_BINARY_SIZE</span><span class="p">);</span>
</span><span class='line'>      <span class="n">binaryMessagePt</span> <span class="o">+=</span> <span class="n">DEVICE_BINARY_SIZE</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>      <span class="cm">/* payload length network order */</span>
</span><span class='line'>      <span class="n">memcpy</span><span class="p">(</span><span class="n">binaryMessagePt</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">networkOrderPayloadLength</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint16_t</span><span class="p">));</span>
</span><span class='line'>      <span class="n">binaryMessagePt</span> <span class="o">+=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">uint16_t</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>      <span class="cm">/* payload */</span>
</span><span class='line'>      <span class="n">memcpy</span><span class="p">(</span><span class="n">binaryMessagePt</span><span class="p">,</span> <span class="n">payloadBuff</span><span class="p">,</span> <span class="n">payloadLength</span><span class="p">);</span>
</span><span class='line'>      <span class="n">binaryMessagePt</span> <span class="o">+=</span> <span class="n">payloadLength</span><span class="p">;</span>
</span><span class='line'>      <span class="k">if</span> <span class="p">(</span><span class="n">SSL_write</span><span class="p">(</span><span class="n">sslPtr</span><span class="p">,</span> <span class="n">binaryMessageBuff</span><span class="p">,</span> <span class="p">(</span><span class="n">binaryMessagePt</span> <span class="o">-</span> <span class="n">binaryMessageBuff</span><span class="p">))</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span>
</span><span class='line'>          <span class="n">rtn</span> <span class="o">=</span> <span class="n">true</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">rtn</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>五. push for iOS客户端-处理push消息</h3>

<p>iOS系统收到push消息后，如果用户点击查看,</p>

<ul>
<li>1.如果应用已经启动，将调用application:didReceiveRemoteNotification的方法：</li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'> <span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">application:</span><span class="p">(</span><span class="n">UIApplication</span> <span class="o">*</span><span class="p">)</span><span class="n">application</span> <span class="nl">didReceiveRemoteNotification:</span><span class="p">(</span><span class="n">NSDictionary</span> <span class="o">*</span><span class="p">)</span><span class="n">userInfo</span> <span class="p">{</span>
</span><span class='line'>      <span class="c1">// userInfo 就是push消息Payload</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li>2.如果应用还没有启动，通过push冷启动后，仍然能在启动后获取Payload：</li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">BOOL</span><span class="p">)</span><span class="nf">application:</span><span class="p">(</span><span class="n">UIApplication</span><span class="o">*</span><span class="p">)</span><span class="nv">application</span> <span class="nf">didFinishLaunchingWithOptions:</span><span class="p">(</span><span class="n">NSDictionary</span><span class="o">*</span><span class="p">)</span><span class="nv">launchOptions</span> <span class="p">{</span>
</span><span class='line'>      <span class="n">NSDictionary</span><span class="o">*</span> <span class="n">userInfo</span> <span class="o">=</span> <span class="p">[</span><span class="n">launchOptions</span> <span class="nl">objectForKey:</span><span class="n">UIApplicationLaunchOptionsRemoteNotificationKey</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span></code></pre></td></tr></table></div></figure>


<h3>六.关于消息控制方面</h3>

<p>  可以在application:didReceiveRemoteNotification控制消息的显示，消失。</p>

<p>例如：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="p">[[</span><span class="n">UIApplication</span> <span class="n">sharedApplication</span><span class="p">]</span> <span class="nl">setApplicationIconBadgeNumber:</span><span class="mi">0</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>详情可参考苹果开发文档<a href="https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html#//apple_ref/doc/uid/TP40008194-CH100-SW5">Apple Push Notification Service</a></p>
</div>
  
  


    </article>
  
  
    <article>
      
  <header>
    
      <h1 class="entry-title"><a href="/blog/2014/10/06/guo-qing-zai-shan-dong/">国庆在山东</a></h1>
    
    
      <p class="meta">
        








  


<time datetime="2014-10-06T22:01:00+08:00" pubdate data-updated="true">Oct 6<span>th</span>, 2014</time>
        
         | <a href="/blog/2014/10/06/guo-qing-zai-shan-dong/#disqus_thread">Comments</a>
        
      </p>
    
  </header>


  <div class="entry-content"><p>国庆十一当天从百悦商务酒店打车去杭州东站，滴滴，快的叫车推送了上百个司机就是无人应答。国庆十一节假日效应啊。在东方威尼斯打车，果然还是线下打车靠谱。这是不是某些情况下互联网O2O的线上尴尬呢？</p>

<p>半个小时到了杭州东站，人挺多的，高铁站的wifi还好，和老婆微信后，看看新闻，听听音乐，等待G42 9:25的高铁。下午13：30到了枣庄高铁站，坐T1到解放路，老婆告诉我，转1路到吴林下，其实应该坛山办事处下，绕远了不少路。</p>

<p>在这几日，有时走走亲戚，帮家里干些简单的农活，果然是离农村太遥远了，稍微干点农活就全身发酸；难怪我们这代人身体素质还赶不上我们父辈呢；</p>
</div>
  
  


    </article>
  
  
    <article>
      
  <header>
    
      <h1 class="entry-title"><a href="/blog/2014/09/30/ios-ji-suan-shi-jian-chai-zhi/">iOS计算时间差值</a></h1>
    
    
      <p class="meta">
        








  


<time datetime="2014-09-30T15:14:00+08:00" pubdate data-updated="true">Sep 30<span>th</span>, 2014</time>
        
         | <a href="/blog/2014/09/30/ios-ji-suan-shi-jian-chai-zhi/#disqus_thread">Comments</a>
        
      </p>
    
  </header>


  <div class="entry-content"><p>iOS中，以1970年1月1日00：00：00起始到现在，计算时间差值，可采用NSDate直接合成计算。如果需要重复计算次数较高，可能会导致NSDate大量生成；有没有更好的方法呢？</p>

<blockquote><p>使用<strong>CFAbsoluteTimeGetCurrent</strong>来计算,减去2001年1月1日00:00:00到1970年1月1日00：00：00差值和时区差值即可。</p></blockquote>

<h4>具体方法</h4>

<h3>1.计算时间差值</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="c1">//1970年1月1日00：00：00到2001年1月1日00:00:00差值和时区差值之和</span>
</span><span class='line'><span class="n">NSString</span> <span class="o">*</span><span class="n">string</span> <span class="o">=</span> <span class="s">@&quot;2001-01-01 00:00:00&quot;</span><span class="p">;</span>
</span><span class='line'><span class="n">NSDateFormatter</span> <span class="o">*</span> <span class="n">formatter</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSDateFormatter</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'><span class="p">[</span><span class="n">formatter</span> <span class="nl">setDateFormat:</span><span class="s">@&quot;yyyy-MM-dd HH:mm:ss&quot;</span><span class="p">];</span>
</span><span class='line'><span class="n">NSDate</span> <span class="o">*</span><span class="n">date</span> <span class="o">=</span> <span class="p">[</span><span class="n">formatter</span> <span class="nl">dateFromString:</span><span class="n">string</span><span class="p">];</span>
</span><span class='line'><span class="n">_deltaTimeSince1970To2001</span> <span class="o">=</span> <span class="p">[</span><span class="n">date</span> <span class="n">timeIntervalSince1970</span><span class="p">]</span> <span class="o">+</span> <span class="p">[</span><span class="n">NSTimeZone</span> <span class="n">systemTimeZone</span><span class="p">].</span><span class="n">secondsFromGMT</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<h3>2.计算当前时间到截止时间的差值,避免了可能大量生成NSDate.</h3>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">TBHDCountDownTimerTimeIntervalType</span><span class="p">)</span><span class="nf">handleTimerEvent:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">sender</span><span class="p">{</span>
</span><span class='line'>
</span><span class='line'><span class="c1">//   NSUInteger timeOffset =  _deadLine - [[NSDate date] timeIntervalSince1970];</span>
</span><span class='line'>    <span class="c1">//减少NSDate对象的消耗</span>
</span><span class='line'>    <span class="n">NSInteger</span> <span class="n">timeOffset</span> <span class="o">=</span>  <span class="n">_deadLine</span> <span class="o">-</span> <span class="n">_deltaTimeSince1970To2001</span> <span class="o">-</span> <span class="n">CFAbsoluteTimeGetCurrent</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">timeOffset</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">NSUInteger</span> <span class="n">dayCount</span> <span class="o">=</span> <span class="n">timeOffset</span><span class="o">/</span><span class="n">KCountDownDay</span><span class="p">;</span>
</span><span class='line'>        <span class="kt">double</span> <span class="n">leftTime</span> <span class="o">=</span> <span class="n">timeOffset</span> <span class="o">-</span> <span class="p">(</span><span class="n">dayCount</span> <span class="o">*</span> <span class="n">KCountDownDay</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">NSUInteger</span> <span class="n">hourCount</span> <span class="o">=</span> <span class="n">leftTime</span> <span class="o">/</span> <span class="mi">3600</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">leftTime</span> <span class="o">=</span> <span class="n">timeOffset</span> <span class="o">-</span> <span class="p">(</span><span class="n">dayCount</span> <span class="o">*</span> <span class="n">KCountDownDay</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="n">hourCount</span> <span class="o">*</span> <span class="mi">3600</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">NSUInteger</span> <span class="n">minuteCount</span> <span class="o">=</span> <span class="n">leftTime</span> <span class="o">/</span> <span class="mi">60</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">leftTime</span> <span class="o">=</span> <span class="n">timeOffset</span> <span class="o">-</span> <span class="p">(</span><span class="n">dayCount</span> <span class="o">*</span> <span class="n">KCountDownDay</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="n">hourCount</span> <span class="o">*</span> <span class="mi">3600</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="n">minuteCount</span> <span class="o">*</span> <span class="mi">60</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">_timeCountBlcok</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">_timeCountBlcok</span><span class="p">(</span><span class="n">dayCount</span><span class="p">,</span><span class="n">hourCount</span><span class="p">,</span><span class="n">minuteCount</span><span class="p">,</span><span class="n">leftTime</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">//根据时间间隔大小调整计时器间隔大小的策略尚未添加。</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">dayCount</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">hourCount</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">return</span> <span class="n">TBHDCountDownTimerTimeIntervalTypeHour</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">dayCount</span> <span class="o">&gt;</span><span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">hourCount</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">minuteCount</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">){</span>
</span><span class='line'>            <span class="k">return</span> <span class="n">TBHDCountDownTimerTimeIntervalTypeMinute</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">else</span><span class="p">{</span>
</span><span class='line'>            <span class="k">return</span> <span class="n">TBHDCountDownTimerTimeIntervalTypeSecond</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">else</span><span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">_timeCountBlcok</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">_timeCountBlcok</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">return</span> <span class="n">TBHDCountDownTimerTimeIntervalTypeNone</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>创建如下:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="n">self</span><span class="p">.</span><span class="n">countDownTimer</span><span class="p">.</span><span class="n">deadLine</span> <span class="o">=</span> <span class="n">_deadLine</span><span class="p">;</span>
</span><span class='line'><span class="n">self</span><span class="p">.</span><span class="n">countDownTimer</span><span class="p">.</span><span class="n">isCountTime</span> <span class="o">=</span> <span class="n">YES</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>销毁如下：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">dealloc</span><span class="p">{</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">_countDownTimer</span><span class="p">.</span><span class="n">isCountTime</span> <span class="o">=</span> <span class="n">NO</span><span class="p">;</span>
</span><span class='line'>    <span class="n">_countDownTimer</span> <span class="o">=</span> <span class="nb">nil</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>其它：明天就回山东了，国庆后回北京，结束在杭州出差的日子^_^.</p>
</div>
  
  


    </article>
  
  
    <article>
      
  <header>
    
      <h1 class="entry-title"><a href="/blog/2014/09/25/guo-qing-jie-hou-hui-jing/">国庆节后回京</a></h1>
    
    
      <p class="meta">
        








  


<time datetime="2014-09-25T20:24:00+08:00" pubdate data-updated="true">Sep 25<span>th</span>, 2014</time>
        
         | <a href="/blog/2014/09/25/guo-qing-jie-hou-hui-jing/#disqus_thread">Comments</a>
        
      </p>
    
  </header>


  <div class="entry-content"><p>在杭州，不知不觉已经半年了;</p>

<p>国庆节后，可以回北京了，那个在北京广告产业园区的办公地点。</p>

<p>在这里，不虚此行</p>

<ul>
<li>1.身体调养的不错，可以时不时去活动。</li>
<li>2.没有那种高强度，快节奏的工作节拍。</li>
<li>3.可以有自己的时间,做些自己想做而一直没有去做的事情。</li>
<li>4.想明白不少以前困惑的事情&hellip;</li>
<li>5.一群不错的小伙伴&hellip;</li>
<li>6&hellip;</li>
</ul>


<p>这会是我人生中里程碑的一段旅程。铭记之，自勉!</p>

<p>亲爱的老婆，我们马上就团聚了^_^</p>
</div>
  
  


    </article>
  
  <div class="pagination">
    
      <a class="prev" href="/blog/page/5/">&larr; Older</a>
    
    <a href="/blog/archives">Blog Archives</a>
    
    <a class="next" href="/blog/page/3/">Newer &rarr;</a>
    
  </div>
</div>
<aside class="sidebar">
  
    <section>
  <h1>关于我</h1>
  <p>律威,QQ:309235009 微信:ksnowlv</p>
  <p>手机单机游戏/手机网游封神online/手机阅读/腾讯iOS地图客户端&实时公交&开放API(地图&街景)/iPad/iPhone淘宝客户端及性能优化</p>
  <p>目前在银客做银客/简理财/&#8230;</p>
  <p>能做一点,是一点;不求大成,不求一万年;积少成多,水到渠成!</p>
</section>
<section>
  <h1>最近发布</h1>
  <ul id="recent_posts">
    
      <li class="post">
        <a href="/blog/2017/04/26/android-drawable/">Android drawable</a>
      </li>
    
      <li class="post">
        <a href="/blog/2017/04/22/iOS-xia-shi-yong-ffmpeg/">iOS下使用ffmpeg</a>
      </li>
    
      <li class="post">
        <a href="/blog/2015/08/19/ios-you-xian-hou-tai-ren-wu/">iOS有限后台任务</a>
      </li>
    
      <li class="post">
        <a href="/blog/2015/08/19/android-xia-jie-ya-suo/">Android下gzip数据流解压缩</a>
      </li>
    
      <li class="post">
        <a href="/blog/2015/08/19/facebook-infer-de-shi-yong/">FaceBook-infer的使用</a>
      </li>
    
  </ul>
</section>
<section>
  <h1>分类</h1>
    <ul id="category-list"><li><a href='/blog/categories/android-jie-ya-suo/'>Android-解压缩 (1)</a></li><li><a href='/blog/categories/androidduo-xian-cheng/'>Android多线程 (3)</a></li><li><a href='/blog/categories/androidcha-jian/'>Android插件 (1)</a></li><li><a href='/blog/categories/androidhui-tu-./'>Android绘图。 (1)</a></li><li><a href='/blog/categories/androidwang-luo/'>Android网络 (1)</a></li><li><a href='/blog/categories/git/'>git (6)</a></li><li><a href='/blog/categories/githubbo-ke/'>github博客 (8)</a></li><li><a href='/blog/categories/ios/'>iOS (6)</a></li><li><a href='/blog/categories/ios-block/'>iOS-block (1)</a></li><li><a href='/blog/categories/ios-bug/'>iOS-Bug (2)</a></li><li><a href='/blog/categories/ios-memory/'>iOS-Memory (4)</a></li><li><a href='/blog/categories/ios-push/'>iOS-push (1)</a></li><li><a href='/blog/categories/ios-ui/'>iOS-UI (2)</a></li><li><a href='/blog/categories/ios-you-hua/'>iOS-优化 (1)</a></li><li><a href='/blog/categories/ios-nei-cun/'>iOS-内存 (1)</a></li><li><a href='/blog/categories/ios-ji-chu/'>iOS-基础 (3)</a></li><li><a href='/blog/categories/ios-duo-xian-cheng/'>iOS-多线程 (3)</a></li><li><a href='/blog/categories/ios-cun-chu/'>iOS-存储 (1)</a></li><li><a href='/blog/categories/ios-an-quan/'>iOS-安全 (1)</a></li><li><a href='/blog/categories/ios-wang-luo/'>iOS-网络 (13)</a></li><li><a href='/blog/categories/ios-jie-ya-suo/'>iOS-解压缩 (1)</a></li><li><a href='/blog/categories/ios-she-ji-mo-shi/'>iOS-设计模式 (1)</a></li><li><a href='/blog/categories/ios-diao-shi/'>iOS-调试 (1)</a></li><li><a href='/blog/categories/iosyou-hua/'>iOS优化 (1)</a></li><li><a href='/blog/categories/iosji-chu/'>iOS基础 (2)</a></li><li><a href='/blog/categories/iosyin-pin/'>iOS音频 (1)</a></li><li><a href='/blog/categories/mac/'>Mac (4)</a></li><li><a href='/blog/categories/mac-duo-xian-cheng/'>Mac-多线程 (1)</a></li><li><a href='/blog/categories/nginx/'>nginx (3)</a></li><li><a href='/blog/categories/php/'>php (3)</a></li><li><a href='/blog/categories/python/'>python (12)</a></li><li><a href='/blog/categories/swift/'>swift (11)</a></li><li><a href='/blog/categories/uml/'>UML (8)</a></li><li><a href='/blog/categories/xcode/'>Xcode (11)</a></li><li><a href='/blog/categories/chan-pin-she-ji/'>产品设计 (2)</a></li><li><a href='/blog/categories/gong-ju/'>工具 (2)</a></li><li><a href='/blog/categories/shu-ju-ku/'>数据库 (2)</a></li><li><a href='/blog/categories/sheng-huo-pian-duan/'>生活片段 (10)</a></li><li><a href='/blog/categories/zhi-ye-sheng-ya/'>职业生涯 (7)</a></li><li><a href='/blog/categories/du-shu/'>读书 (2)</a></li></ul>
</section>
<section>
  <h1>外部链接</h1>
    <ul id="外部链接">
    	<li><a href="https://developer.apple.com">苹果开发者中心</a> </li>
    	<li><a href="http://stackoverflow.com/questions/tagged/ios">stackoverflow</a></li>
    	<li><a href="http://ksnowlv.blog.163.com/blog/#m=0">ksnowlv网易博客</a></li>
	</ul>
</section>

  
</aside>

    </div>
  </div>
  <footer role="contentinfo"><p>
  Copyright &copy; 2017 - 律威 -
  <span class="credit">Powered by <a href="http://octopress.org">Octopress</a></span>

  <script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1253538110'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "v1.cnzz.com/z_stat.php%3Fid%3D1253538110%26online%3D1' type='text/javascript'%3E%3C/script%3E"));</script>

  <script type="text/javascript">
var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3F4c1727a94ea20751730e8a556dbdbf82' type='text/javascript'%3E%3C/script%3E"));
</script>

</p>



</footer>
  

<script type="text/javascript">
      var disqus_shortname = 'ksnowlv';
      
        
        var disqus_script = 'count.js';
      
    (function () {
      var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
      dsq.src = 'http://' + disqus_shortname + '.disqus.com/' + disqus_script;
      (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    }());
</script>








</body>
</html>
